package cc.admin.modules.graduate.service.impl;

import cc.admin.common.api.vo.Result;
import cc.admin.common.exception.CcAdminException;
import cc.admin.common.sys.query.QueryGenerator;
import cc.admin.common.sys.vo.DictModel;
import cc.admin.common.sys.vo.LoginUser;
import cc.admin.common.util.oConvertUtils;
import cc.admin.modules.graduate.entity.ChoiceQuestions;
import cc.admin.modules.graduate.entity.Topic;
import cc.admin.modules.graduate.mapper.ChoiceQuestionsMapper;
import cc.admin.modules.graduate.mapper.TopicMapper;
import cc.admin.modules.graduate.service.IChoiceQuestionsService;
import cc.admin.modules.sys.service.ISysUploadTemplateService;
import cc.admin.poi.excel.ExcelExportUtil;
import cc.admin.poi.excel.ExcelImportUtil;
import cc.admin.poi.excel.def.NormalExcelConstants;
import cc.admin.poi.excel.entity.ExportParams;
import cc.admin.poi.excel.entity.ImportParams;
import cc.admin.poi.excel.export.ExcelExportServer;
import cc.admin.poi.excel.view.PoiEntityExcelView;
import cc.admin.poi.util.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.utils.UuidUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId;

/**
 * @Description: 选择题
 * @Author: cc-admin
 * @Date: 2024-12-21
 * @Version: V1.0.0
 */
@Service
@Slf4j
public class ChoiceQuestionsServiceImpl extends ServiceImpl<ChoiceQuestionsMapper, ChoiceQuestions> implements IChoiceQuestionsService {

    @Autowired
    private TopicMapper topicMapper;

    public static final Map<String, String> topicMap = new HashMap<>();

    static {
        topicMap.put("计算机", "01");
        topicMap.put("数学", "02");
        topicMap.put("政治", "04");
    }

    /**
     * 导出excel
     *
     * @param request
     */
    @Override
    public ModelAndView exportXls(HttpServletRequest request, String choiceQuestionIds, String catalog, Class<ChoiceQuestions> clazz, String title) {
        LambdaQueryWrapper<Topic> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.isNotNull(Topic::getParentId);
        queryWrapper1.ne(Topic::getParentId,"");
        String[] labelArray = topicMapper.selectList(queryWrapper1).stream()
                .map(Topic::getLabel)
                .toArray(String[]::new);
        // Step.1 组装查询条件
        QueryWrapper<ChoiceQuestions> queryWrapper = QueryGenerator.initQueryWrapper(new ChoiceQuestions(), request.getParameterMap());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (choiceQuestionIds != null && !choiceQuestionIds.isEmpty()) {
            queryWrapper.in("id", Arrays.asList(choiceQuestionIds.split(",")));
        }else {
            //让他查不着数据
            queryWrapper.eq("id","");
        }
        if (catalog != null && !catalog.isEmpty()) {
            queryWrapper.eq("major_id", catalog);
        }
        // Step.2 获取导出数据
        List<ChoiceQuestions> pageList = this.list(queryWrapper);
        List<ChoiceQuestions> exportList = null;

        // 过滤选中数据
        String selections = request.getParameter("selections");
        if (oConvertUtils.isNotEmpty(selections)) {
            List<String> selectionList = Arrays.asList(selections.split(","));
            exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
        } else {
            exportList = pageList;
        }


        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new PoiEntityExcelView() {
            @Override
            protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
                String codedFileName = "临时文件";
                Workbook workbook = null;
                //---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
                String[] exportFields = null;

                Object exportFieldStr = model.get(NormalExcelConstants.EXPORT_FIELDS);
                if (exportFieldStr != null && exportFieldStr != "") {
                    exportFields = exportFieldStr.toString().split(",");
                }
                //---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
                if (model.containsKey(NormalExcelConstants.MAP_LIST)) {
                    List<Map<String, Object>> list = (List<Map<String, Object>>) model.get(NormalExcelConstants.MAP_LIST);
                    if (list.size() == 0) {
                        throw new RuntimeException("MAP_LIST IS NULL");
                    }
                    workbook = ExcelExportUtil.exportExcel((ExportParams) list.get(0).get(NormalExcelConstants.PARAMS), (Class<?>) list.get(0).get(NormalExcelConstants.CLASS), (Collection<?>) list.get(0).get(NormalExcelConstants.DATA_LIST), exportFields);
                    for (int i = 1; i < list.size(); i++) {
                        new ExcelExportServer().createSheet(workbook, (ExportParams) list.get(i).get(NormalExcelConstants.PARAMS), (Class<?>) list.get(i).get(NormalExcelConstants.CLASS), (Collection<?>) list.get(i).get(NormalExcelConstants.DATA_LIST), exportFields);
                    }
                } else {
                    workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(NormalExcelConstants.PARAMS), (Class<?>) model.get(NormalExcelConstants.CLASS), (Collection<?>) model.get(NormalExcelConstants.DATA_LIST), exportFields);
                }
                // 在这里进行自定义操作，例如添加下拉列表
                if (workbook != null && workbook.getNumberOfSheets() > 0) {
                    Sheet targetSheet = workbook.getSheetAt(0);
                    ExcelUtil.addValidationToSheet(workbook, targetSheet, labelArray, 'I', 3, 1000);
                    ExcelUtil.addValidationToSheet(workbook, targetSheet, new Object[]{"计算机", "数学", "政治"}, 'A', 3, 1000);
                }
                if (model.containsKey(NormalExcelConstants.FILE_NAME)) {
                    codedFileName = (String) model.get(NormalExcelConstants.FILE_NAME);
                }
                if (workbook instanceof HSSFWorkbook) {
                    codedFileName += HSSF;
                } else {
                    codedFileName += XSSF;
                }
                if (isIE(request)) {
                    codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8");
                } else {
                    codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1");
                }
                response.setHeader("content-disposition", "attachment;filename=" + codedFileName);
                ServletOutputStream out = response.getOutputStream();
                workbook.write(out);
                out.flush();
            }

        });
        mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.CLASS, clazz);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title));
        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
        return mv;
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<ChoiceQuestions> choiceQuestionsClass) {
        HashMap<String, String> childTopicMap = new HashMap<>();
// 查询数据并封装成 Map
        Map<String, String> resultMap = topicMapper.selectList(null).stream()
                .collect(Collectors.toMap(Topic::getLabel, Topic::getValue, (existing, replacement) -> existing, HashMap::new));
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                List<ChoiceQuestions> list = ExcelImportUtil.importExcel(file.getInputStream(), choiceQuestionsClass, params);
                list.forEach(item -> {
                    String id = UuidUtils.getUUID();
                    item.setId(id);
                    String subjectText = item.getSubjectText();
                    String subjectId = ChoiceQuestionsServiceImpl.topicMap.get(subjectText);
                    item.setSubjectId(subjectId);
                    String majorText = item.getMajorText();
                    String majorId = resultMap.get(majorText);
                    item.setMajorId(majorId);
                });
                //update-begin-author:taoyan date:20190528 for:批量插入数据
                long start = System.currentTimeMillis();
                this.saveBatch(list);
                //400条 saveBatch消耗时间1592毫秒  循环插入消耗时间1947毫秒
                //1200条  saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                //update-end-author:taoyan date:20190528 for:批量插入数据
                return Result.ok("文件导入成功！数据行数：" + list.size());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }


    // 假设的添加下拉列表方法，实际使用时请确保其正确实现
//    private void addValidationToSheet(Workbook workbook, Sheet targetSheet, Object[] options, char column, int fromRow, int endRow) {
//        // 实现具体的添加下拉列表逻辑
//        // 例如：
//        // 这里省略具体实现，你可以参考之前提供的 addValidationToSheet 方法的逻辑来完善
//
//    }

    private boolean isIE(HttpServletRequest request) {
        String userAgent = request.getHeader("USER-AGENT").toLowerCase();
        return userAgent.indexOf("msie") > 0 || userAgent.indexOf("trident") > 0;
    }
}
